import React, {useEffect, useState} from 'react';
import {Modal, Form, Input, Checkbox, Row, Col, message, Button} from 'antd';
import {deepCopy, http} from 'libs';
import {Action} from "components";
import routes from "@/routes";
import store from './store';
import {observer} from "mobx-react";
import lds from "lodash";
import css from './index.module.less';

export default observer(function () {
  const [form] = Form.useForm()
  const [loading, setLoading] = useState(false)
  const [allAuths, setAllAuths] = useState([]); // 所有权限数据
  const [indeterminate, setIndeterminate] = useState([]); // 一级选择框的 是否全选状态
  const [checkAll, setCheckAll] = useState([]); // 一级选择框的 是否选择状态
  const [checkedList, setCheckedList] = useState([]); // 所有checkbox.group已选项

  useEffect(() => {
    initData(store.record?.permissions)
  }, [store.record])

  function initData(permissions = []) {
    routes.map((route, index) => {
      let auths = getRouteAuth(route, route.child ? [] : [route.auth])
      let checkAuths = auths.filter(v => permissions.includes(v))
      allAuths[index] = auths
      checkedList[index] = checkAuths
      checkAll[index] = checkAuths.length === auths.length
      indeterminate[index] = (checkAuths.length !== auths.length) && checkAuths.length
      return true
    })
    setAllAuths([...allAuths])// 全部权限
    setCheckedList([...checkedList])
    setCheckAll([...checkAll])
    setIndeterminate([...indeterminate])
  }

  function handleSubmit(formData) {
    setLoading(true);
    formData['id'] = store.record.id
    formData['permissions'] = lds.flatten(checkedList)
    http.post('/api/user/role/', formData)
      .then(res => {
        message.success(res.data || '操作成功')
        store.fetchRecords()
        store.set('formVisible', false)
      })
      .finally(() => setLoading(false))
  }

  // 获取菜单权限数组
  function getRouteAuth(route, auths, exclude = []) {
    // 加入子菜单权限
    route.child && route.child.map(v => {
      auths.push(v.auth)
      // 加入子菜单actions权限
      if (v.actions) {
        let aAuths = v.actions.map(c => v.auth + '.' + c.auth)
        auths = auths.concat(aAuths)
      }
      return true
    })

    // 加入actions权限
    if (route.actions) {
      let aAuths = route.actions.map(v => route.auth + '.' + v.auth)
      auths = auths.concat(aAuths)
    }

    // 删除需要排除的项目
    auths = auths.filter(v => !exclude.includes(v) && v)

    return auths
  }


  // 一级分类全选
  function onCheckAllChange(e, index) {
    let auths = allAuths[index]
    let list = deepCopy(checkedList)
    let curVal = list[index] ?? []

    indeterminate[index] = false
    checkAll[index] = e.target.checked

    if (e.target.checked) {
      curVal = [...new Set([...curVal, ...auths])]
    } else {
      curVal = []
    }
    list[index] = curVal//lds.uniq(curVal)
    setCheckedList([...list])
    setIndeterminate([...indeterminate]);
    setCheckAll([...checkAll]);
  }

  // 二级分类全选
  function onChange(list, index) {
    let auths = allAuths[index]
    let checked = deepCopy(checkedList)
    /*
         如果变更的是action，关联修改page的权限；
         如果变更的是page，关联修改action的权限；
    */
    list = getRelationAuth(list, index)
    checked[index] = [...list]

    indeterminate[index] = !!list.length && list.length < auths.length
    checkAll[index] = list.length === auths.length
    setIndeterminate([...indeterminate]);
    setCheckAll([...checkAll]);
    setCheckedList([...checked])
  }

  // 获取关联auth.
  // auth：变更的checkbox;
  // auths：变更所在页面的所有权限；
  // list：所在页面当前的选择状态
  function getRelationAuth(list, index) {
    let {diffAuth, isAdd} = getDiff(checkedList[index] ?? [], list) // 获取变更项，以及是 选中 还是 取消选中
    let arr = diffAuth.split('.')
    let actionAuths = allAuths[index].filter(v => v.includes(arr[0] + '.')) // 对应页面操作权限
    let relationAuth = []
    // 2：页面权限变更
    if (arr.length === 1) {
      relationAuth = actionAuths
    }

    // 3：操作权限变更
    if (arr.length === 2 && isAdd) {
      relationAuth = [arr[0]]
    }

    if (isAdd) {
      list = list.concat(relationAuth)
    } else if (arr.length === 1) {
      list = list.filter(v => !relationAuth.includes(v))
    } else {
      // 一级菜单下的 操作权限 取消选中时，会丢失菜单权限。单独处理
      list.push(arr[0])
    }
    return [...new Set(list)]
  }

  // 修改内容获取
  function getDiff(prev, next) {
    let a
    let b
    let isAdd
    let diff
    if (prev.length > next.length) {
      a = [...prev]
      b = [...next]
      isAdd = false
    } else {
      a = [...next]
      b = [...prev]
      isAdd = true
    }

    diff = a.filter(v => !b.includes(v))
    if (diff.length > 1) {
      // 一级菜单下的 操作权限 取消选中时，会丢失菜单权限。单独处理
      diff = diff.find(v => v.includes('.'))
    } else {
      diff = diff[0]
    }
    return {diffAuth: diff, isAdd: isAdd}
  }

  function handleCheckAll(checked) {
    let auths = []
    if (checked) {
      auths = lds.flatten(allAuths)
    }
    initData(auths)
  }

  return (
    <Modal
      open
      width={850}
      maskClosable={false}
      autoComplete="off"
      title={store.record.id ? '修改角色' : '新建角色'}
      onCancel={store.vSet('formVisible', false)}
      confirmLoading={loading}
      onOk={form.submit}>
      <Form form={form} onFinish={handleSubmit} initialValues={store.record} labelCol={{span: 2}}
            wrapperCol={{span: 21}}>
        <Form.Item required name="name" label="角色名">
          <Input style={{width: 252}} autoComplete='off' placeholder="请输入"/>
        </Form.Item>

        <Form.Item required label="权限"
                   extra={
                     <div>
                       <span style={{marginRight: 16}}>已选择{lds.flatten(checkedList).length}个权限</span>
                       <Action>
                         <Action.Button type="link" onClick={() => handleCheckAll(true)}>全选</Action.Button>
                         <Action.Button type="link" danger onClick={() => handleCheckAll(false)}>清空</Action.Button>
                       </Action>
                     </div>
                   }>
          <div className={css.box}>
            <table className={css.fixTable} border="1">
              <thead>
              <tr>
                <th className={css.td1}>模块</th>
                <th className={css.td2}>页面</th>
                {/*<th>按钮</th>*/}
              </tr>
              </thead>
            </table>
            <table className={css.table} border="1">
              <thead>
              <tr>
                <th className={css.td1}>模块</th>
                <th className={css.td2}>页面</th>
                {/*<th>按钮</th>*/}
              </tr>
              </thead>
              <tbody>
              {
                routes.map((item, index) => {
                  return (
                    <tr key={'l1-' + item.auth}>

                      <td key={checkedList[index]?.length ?? index}>
                        <Checkbox indeterminate={indeterminate[index]}
                                  onChange={(e) => onCheckAllChange(e, index)}
                                  checked={checkAll[index]}>
                          <b>{item.title}</b>
                        </Checkbox>
                      </td>

                      <td colSpan={2} className={css.posTd}>
                        {
                          // 有子菜单页面时，主页面不会有action操作，两者互斥
                          item.child ? (
                            <Checkbox.Group value={checkedList[index]}
                                            onChange={val => onChange(val, index)}
                                            className={css.group}>
                              <table border="1" className={css.innerTable}>
                                <tbody>
                                {
                                  item.child.filter(c => c.auth || c.actions?.length).map((c, i) => (
                                    <tr key={'l2-col-' + c.auth + i}>
                                      <td className={css.td2}>
                                        <Checkbox value={c.auth}>{c.title}</Checkbox>
                                      </td>

                                      {/*<td>*/}
                                      {/*  <Row>*/}
                                      {/*    {*/}
                                      {/*      c?.actions?.map(a => (*/}
                                      {/*        <Col span={8} key={'l3-col-op-' + c.auth + a.auth}>*/}
                                      {/*          <Checkbox value={c.auth + '.' + a.auth}>{a.title}</Checkbox>*/}
                                      {/*        </Col>*/}
                                      {/*      ))*/}
                                      {/*    }*/}
                                      {/*  </Row>*/}
                                      {/*</td>*/}
                                    </tr>
                                  ))
                                }
                                </tbody>
                              </table>

                            </Checkbox.Group>
                          ) : (
                            <Checkbox.Group value={checkedList[index]}
                                            onChange={val => onChange(val, index)}
                                            className={css.group}>
                              <table border="1" className={css.innerTable}>
                                <tbody>
                                <tr>
                                  <td className={css.td2}>
                                    <Checkbox value={item.auth}>{item.title}</Checkbox>
                                  </td>
                                  {/*<td>*/}
                                  {/*  <Row>*/}
                                  {/*    {*/}
                                  {/*      item?.actions?.map(a => (*/}
                                  {/*        <Col span={8} key={'le1-col-op-' + item.auth + a.auth}>*/}
                                  {/*          <Checkbox value={item.auth + '.' + a.auth}>*/}
                                  {/*            {a.title}*/}
                                  {/*          </Checkbox>*/}
                                  {/*        </Col>*/}
                                  {/*      ))*/}
                                  {/*    }*/}
                                  {/*  </Row>*/}
                                  {/*</td>*/}
                                </tr>
                                </tbody>
                              </table>

                            </Checkbox.Group>
                          )
                        }
                      </td>

                    </tr>

                  )
                })
              }
              </tbody>
            </table>

            {/*{*/}
            {/*  routes.map((item, index) => {*/}
            {/*    return (*/}
            {/*      <div key={'l1-' + item.auth} style={{*/}
            {/*        borderBottom: '1px solid #fff',*/}
            {/*        padding: '0 10px 10px',*/}
            {/*      }}>*/}

            {/*        <div style={{*/}
            {/*          whiteSpace: "nowrap",*/}
            {/*          textAlign: "left",*/}
            {/*          marginTop: 15,*/}
            {/*          marginRight: 10,*/}
            {/*          marginBottom: 10,*/}
            {/*        }} key={checkedList[index]?.length ?? index}>*/}
            {/*          <Checkbox indeterminate={indeterminate[index]}*/}
            {/*                    onChange={(e) => onCheckAllChange(e, index)}*/}
            {/*                    checked={checkAll[index]}>*/}
            {/*            <b style={{color: '#1890ff'}}>{item.title}</b>*/}
            {/*          </Checkbox>*/}
            {/*        </div>*/}

            {/*        <div style={{marginLeft: 24}}>*/}
            {/*          {*/}
            {/*            // 有子菜单页面时，主页面不会有action操作，两者互斥*/}
            {/*            item.child ? (*/}
            {/*              <Checkbox.Group value={checkedList[index]}*/}
            {/*                              onChange={val => onChange(val, index)}*/}
            {/*                              style={{width: '100%'}}>*/}
            {/*                {*/}
            {/*                  item?.child?.filter(c => c.auth || c.actions?.length).map((c, i) => (*/}
            {/*                    <div key={'l2-col-' + c.auth + i} style={{marginBottom: 10}}>*/}
            {/*                      <Checkbox value={c.auth} indeterminate={false}>*/}
            {/*                        <span style={{color: '#1890ff'}}>{c.title}</span>*/}
            {/*                      </Checkbox>*/}
            {/*                      <div style={{marginLeft: 24}}>*/}
            {/*                        <Row>*/}
            {/*                          {*/}
            {/*                            c?.actions?.map(a => (*/}
            {/*                              <Col span={6} key={'l3-col-op-' + c.auth + a.auth}>*/}
            {/*                                <Checkbox value={c.auth + '.' + a.auth}>{a.title}</Checkbox>*/}
            {/*                              </Col>*/}
            {/*                            ))*/}
            {/*                          }*/}
            {/*                        </Row>*/}
            {/*                      </div>*/}
            {/*                    </div>*/}
            {/*                  ))*/}
            {/*                }*/}
            {/*              </Checkbox.Group>*/}
            {/*            ) : item.actions ? (*/}
            {/*              <Checkbox.Group value={checkedList[index]}*/}
            {/*                              onChange={val => onChange(val, index)}*/}
            {/*                              style={{width: '100%'}}>*/}
            {/*                <Row>*/}
            {/*                  {*/}
            {/*                    item?.actions?.map(a => (*/}
            {/*                      <Col span={6} key={'le1-col-op-' + item.auth + a.auth}>*/}
            {/*                        <Checkbox value={item.auth + '.' + a.auth}>*/}
            {/*                          {a.title}*/}
            {/*                        </Checkbox>*/}
            {/*                      </Col>*/}
            {/*                    ))*/}
            {/*                  }*/}
            {/*                </Row>*/}
            {/*              </Checkbox.Group>*/}
            {/*            ) : null*/}
            {/*          }*/}
            {/*        </div>*/}

            {/*      </div>*/}

            {/*    )*/}
            {/*  })*/}
            {/*}*/}
          </div>
        </Form.Item>

      </Form>
    </Modal>
  )
})
